﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections;
using IridiumParser;

namespace IridiumFlares
{
    public class PageParser
    {
        private string content = null;
        private string url = null;
        private Match match = null;
        private ArrayList flareList = new ArrayList();

        //private const string RegTable = @"<th>Distance to.+Satellite</TH></tr>([\s\S]+)</table><p>";
        private const string RegTable = @"<th>Distance to([\s\S]+)</table><p>";
        private const string RegFlare = @"<tr>([\s\S]+?)</tr>";

        public PageParser(String _url)
        {
            this.url = _url;
            this.getFile();
        }

        public PageParser(StringBuilder content)
        {
            this.content = content.ToString();
        }

        private void getFile()
        {
            this.content = GetPage(url);
        }

        public Flare[] parse()
        {
            if (content == null) getFile();
            match = Regex.Match(content, RegTable);
            if (!match.Success)
            {
                Console.WriteLine("No table with flare information found!");
                return null;
            }
            getFlareContents(match.Groups[1].ToString());
            return (Flare[]) this.flareList.ToArray(typeof (Flare));
        }

        private void getFlareContents(String table)
        {
            int index = 0;
            int count = 0;
            while((match = Regex.Match(table, RegFlare)).Success){
                Group g = match.Groups[1];
                //Console.WriteLine("--------------------\n" + g + "\n--------------------\n");
                flareList.Add(FlareParser.parseHTML(g.ToString()));
                index = match.Index + g.ToString().Length;
                Console.WriteLine("Index: "+index);
                table = table.Substring(index);
                count++;
            }
            Console.WriteLine(count+ "flares found");
        }

        private String GetPage(string url)
        {
            WebResponse response = null;
            Stream stream = null;
            StreamReader reader = null;
            StringBuilder buffer = new StringBuilder();

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                response = request.GetResponse();
                stream = response.GetResponseStream();

                if (!response.ContentType.ToLower().StartsWith("text/")) return null;

                reader = new StreamReader(stream);
                String line = null;
                while ((line = reader.ReadLine()) != null)
                {
                    buffer.Append(line + "\r\n");
                }
                return buffer.ToString();

            }
            catch (WebException e)
            {
                System.Console.WriteLine("Can't download:" + e);
                return null;
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Can't download:" + e);
                return null;
            }
            finally
            {
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (response != null) response.Close();
            }
        }

        public Flare[] getFlaresWithCriteria(String _start, String _end, int brighterThan)
        {
            TimeSpan start;
            TimeSpan end;
            try
            {
                start = TimeSpan.Parse(_start);
                end = TimeSpan.Parse(_end);
            }
            catch (Exception)
            {
                throw new Exception("Could not parse time string");
            }
            
            var flares = from Flare f in flareList
                         where f.Time.TimeOfDay >= start && f.Time.TimeOfDay <= end && f.Intensity < brighterThan
                         select f;
            return flares.ToArray();
        }

        public Flare[] getFlaresWithCriteria(int brighterThan)
        {
            var flares = from Flare f in flareList
                         where f.Intensity < brighterThan
                         select f;
            return flares.ToArray();
        }
    }
}
